<?php
	require_once ( 'AbstractDAO.php' );
	
	class GiftCouponDAO extends AbstractDAO 
	{

//--------------------------coupon functions---------------------------------
		
		public function GetCouponList(&$totalNum, $type, $cpage=1,$perpage=15)
		{
			$cacheManager = GetCacheManager();
			$re_totalNum = $cacheManager->Get( "coupon_totalnum_".$type, CNS_COUPON_GIFT );
			$re_coupon = $cacheManager->Get( "coupon_list_".$type.'_'.$perpage."_".$cpage, CNS_COUPON_GIFT );
			if( $re_totalNum !== false && $re_coupon!==false)
			{
				$totalNum = $re_totalNum;
				return $re_coupon;
			}
				
			$now_time=strtotime(GetCurrentDate());
			$sql="select * from coupon where coupon_status=1 ";
			if($type===0)
				$sql=$sql."and coupon_per_price=0";
			else
				$sql=$sql."and coupon_per_price>0";
			$tmp = $this->db->GetPlan( $sql );
			
			if($tmp===false)
			{
				$totalNum=0;
				return false;
			}
			else
			{
				$coupons=array();
				foreach($tmp as $key=>$coupon)
				{
					$types=explode(",",$coupon['coupon_type']);
					if(in_array("1", $types))
					{
						$start_time=strtotime($coupon['coupon_start_date']);
						$end_time=strtotime($coupon['coupon_end_date']);
						if($now_time<$start_time||$now_time>$end_time)
							continue;
					}
					if(in_array("2", $types))
					{
						if($coupon['coupon_total_num']<=0)
							continue;
					}
					$coupons[]=$coupon;
				}
				$totalNum=count($coupons);
				$start=($cpage-1)*$perpage;
				if($totalNum===0||$start>=$totalNum)
					return false;
				else
				{
					$resultCoupons=array_slice($coupons, $start, $perpage);
					$cacheManager->Set( "coupon_totalnum_".$type, $totalNum, CNS_COUPON_GIFT );
					$cacheManager->Set( "coupon_list_".$type.'_'.$perpage."_".$cpage, $resultCoupons, CNS_COUPON_GIFT );
					return $resultCoupons;
				}
			}
		}
		
		/*
		 * 用户获取优惠券函数
		 * $coupon: 返回优惠券信息
		 * return 1， 获取优惠券密钥成功
		 * return 2， 无效的优惠券
		 * return 3， 用户段换数目超过剩余上限
		 * return 4， 用户E币不够
		 * return 5, 内部错误
		 */
		public function BuyCoupon($userId, $couponId, &$coupon, $quantity=1 )
		{
			$now=GetCurrentDate();
			
			$this->db->BeginTransaction();
			try
			{
				$sql="select * from coupon where coupon_status=1 and coupon_id=$couponId for update";
				$coupon=$this->db->GetRow($sql);
				if($coupon===false)
				{
					$this->db->Commit();
					return 2;
				}
				
				$types=explode(",",$coupon['coupon_type']);
				if(in_array("1", $types))
				{
					$now_time=strtotime($now);
					$start_time=strtotime($coupon['coupon_start_date']);
					$end_time=strtotime($coupon['coupon_end_date']);
					if($now_time<$start_time||$now_time>$end_time)
					{
						$this->db->Commit();
						return 2;
					}
				}
				if(in_array("2", $types))
				{
					if($coupon['coupon_total_num']<=0)
					{
						$this->db->Commit();
						return 2;
					}
					if($coupon['coupon_total_num']<$quantity)
					{
						$this->db->Commit();
						return 3;
					}
				}
	
				//Check enough coin
				if($coupon['coupon_per_price']>0)
				{
					$cost=$coupon['coupon_per_price']*$quantity;
					$userDAO=GetUserDAO();
					if($userDAO->GetCoinByUid($userId)<$cost)
					{
						$this->db->Commit();
						return 4;
					}
				}
			
				//step 1, reduce the coin of user
				if($coupon['coupon_per_price']>0)
				{
					$cost=$coupon['coupon_per_price']*$quantity;
					$sql="update user_statistic set coins=coins-$cost where user_id=$userId";
					$this->db->Update( $sql );
				}
				
				//step 2, reduce the total number if necessary
				if(in_array("2", $types))
				{
					$sql="update coupon set coupon_total_num=coupon_total_num-$quantity where coupon_id=$couponId";
					$this->db->Update( $sql );
				}
				
				//step 3, modify the coupon key if necessary
				/*
				if(in_array("12", $types))
				{
					//启动动态计算程序,$coupon['coupon_key']=....
				}
				*/
				
				//step 4, log the history
				$status=1; 
				if(in_array("11", $types))
					$key=$coupon['coupon_key'];
				else
					$key='';
				
				if($coupon['coupon_per_price']>0)
				{
					//if necessary, modify the value of $status into 0
					$sql="insert into coupon_history(user_id, coupon_id, coupon_exchange_quantity, coupon_exchange_date, note1, note2, coupon_process_status) 
					values( $userId, $couponId, $quantity, '$now', '$key', '', $status)";
					$this->db->Insert( $sql );
				}
				else
				{
					$sql="select * from coupon_history where user_id=$userId and coupon_id=$couponId";
					$tmp=$this->db->GetRow($sql);
					if($tmp==false)
					{
						$sql="insert into coupon_history(user_id, coupon_id, coupon_exchange_quantity, coupon_exchange_date, note1, note2, coupon_process_status) 
						values( $userId, $couponId, $quantity, '$now', '$key', '', $status)";
						$this->db->Insert( $sql );
					}
					else
					{
						$sql="update coupon_history set 
						coupon_exchange_quantity=$quantity, 
						coupon_exchange_date='$now', 
						note1='$key', 
						coupon_process_status=$status 
						where user_id=$userId and coupon_id=$couponId";
						$this->db->Update( $sql );
					}
				}
				
				$this->db->Commit();
				return 1;
			}
			catch( Exception $e )
			{
				$this->db->Rollback();
		    	return 5;
			}
		}
		
		public function GetCouponByID($couponID)
		{
			$sql="select * from coupon where coupon_status=1 and coupon_id=$couponID";
			return $this->db->GetRow($sql);
		}
		
		public function GetHotCoupon( $count=10 )
		{
			
			$cacheManager = GetCacheManager();
			$re = $cacheManager->Get( "HotCoupon_".$count, CNS_COUPON_GIFT );
			
			if( $re !== false )
				return $re;
			
			$now=GetCurrentDate();
			$now_time=strtotime($now);
			$sql="select c.coupon_id, c.coupon_name, c.coupon_picture, c.coupon_start_date, c.coupon_end_date,
			c.coupon_total_num, c.coupon_per_price, c.coupon_type, c.coupon_status, (case WHEN coupon_history_id 
			IS NULL THEN 0 ELSE count(*) END ) as buy_num from coupon c
			left join coupon_history ch on c.coupon_id=ch.coupon_id group by c.coupon_id having c.coupon_status=1
			order by buy_num desc";
			$tmp=$this->db->GetPlan($sql);
			
			if($tmp==false)
			{
				return false;
			}
			else
			{
				$coupons=array();
				foreach($tmp as $key=>$coupon)
				{
					$types=explode(",",$coupon['coupon_type']);
					if(in_array("1", $types))
					{
						$start_time=strtotime($coupon['coupon_start_date']);
						$end_time=strtotime($coupon['coupon_end_date']);
						if($now_time<$start_time||$now_time>$end_time)
							continue;
					}
					if(in_array("2", $types))
					{
						if($coupon['coupon_total_num']<=0)
							continue;
					}
					$coupons[]=$coupon;
				}
				if(count($coupons)===0)
					return false;
				else
				{
					$hotCoupon=array_slice($coupons, 0, $count);
					$cacheManager->Set( "HotCoupon_".$count, $hotCoupon, CNS_COUPON_GIFT );
					return $hotCoupon;
				}
			}
		}
		
		public function GetRecentHistory( $count=20 )
		{
			/*
			$cacheManager = GetCacheManager();
			$re = $cacheManager->Get( 'RecentCouponHistory', CNS_COUPON_GIFT );	
			
			if( $re !== false )
				return $re;
			*/
			
			$sql="select ch.user_id, ubi.nick, ch.coupon_id, c.coupon_name, c.coupon_status, TIMESTAMPDIFF( MINUTE, ch.coupon_exchange_date, NOW()) as timediff from user_basic_info ubi, coupon c, coupon_history ch where ch.coupon_id=
			c.coupon_id and ch.user_id=ubi.id order by ch.coupon_exchange_date desc limit 0,".$count;
			$result=$this->db->GetPlan($sql);
			
			if(!$result)
				return false;

			$eventList=array();
			foreach($result as $key=>$value)
			{
				if($value['timediff']>=0&&$value['timediff']<60)
					$value['timediff']=$value['timediff'].'分钟前';
				else
				{
					if($value['timediff']>=60&&$value['timediff']<1440)
						$value['timediff']=floor($value['timediff']/60).'小时前';
					else
					{
						if($value['timediff']>=1440&&$value['timediff']<43200)
							$value['timediff']=floor($value['timediff']/1440).'天前';
						else
							$value['timediff']=floor($value['timediff']/43200).'月前';
					}
				}
				$eventList[]=$value;
			}
			return $eventList;
			
			//return $this->db->GetPlan($sql, true, CNS_COUPON_GIFT, 'RecentCouponHistory');
		}
		
		public function GetHistoryByCouponID( $couponID, $count=20 )
		{
			$sql="select ubi.nick, us.contribution, ch.* from user_basic_info ubi, user_statistic us, coupon_history ch   
			where ubi.id=ch.user_id and us.user_id=ch.user_id and ch.coupon_id=$couponID  
			order by coupon_exchange_date desc limit 0".$count;
			return $this->db->GetPlan($sql);
		}
		
		public function GetConsumptionCountByUid( $userID, $type )
		{
			if($type===0)
				$sql="select count(*) from coupon_history where user_id=$userID";
			else
			{
				//去除未中奖的记录
				$sql="select count(*) from gift_history where user_id=$userID and note2<>'0'";
			}
			return $this->db->GetValue($sql);
		}
		
		public function GetConsumptionByUid( $userID, $type, $cpage=1,$perpage=20 )
		{
			if($type==0)
			{
				$sql="select ch.coupon_id, ch.coupon_exchange_date as exchange_date, ch.coupon_process_status as process_status, 
				ch.note1, c.coupon_name as name, c.coupon_per_price as price, c.coupon_status as status from 
				coupon_history ch, coupon c where ch.coupon_id=c.coupon_id and ch.user_id=$userID order by 
				ch.coupon_exchange_date desc";
			}
			else
			{
				$sql="select gh.gift_id, gh.gift_exchange_date as exchange_date, gh.process_status, gh.note1, 
				g.gift_name as name, g.gift_per_price as price, g.gift_status as status from 
				gift_history gh, gift g where gh.gift_id=g.gift_id and gh.user_id=$userID and note2<>'0' order by 
				gh.gift_exchange_date desc";
			}
			return $this->getRows($sql, $perpage, $cpage);
		}
		
		public function GetGiftList( &$totalNum, $cpage=1,$perpage=15 )
		{
			$cacheManager = GetCacheManager();
			$re_totalNum = $cacheManager->Get( "gift_totalnum", CNS_COUPON_GIFT );
			$re_gift = $cacheManager->Get( "gift_list_".$perpage."_".$cpage, CNS_COUPON_GIFT );
			if( $re_totalNum !== false && $re_gift!==false)
			{
				$totalNum = $re_totalNum;
				return $re_gift;
			}
			$now_time=strtotime(GetCurrentDate());
			$sql="select * from gift where gift_status=1";
			$tmp = $this->db->GetPlan( $sql );
			if($tmp===false)
			{
				$totalNum=0;
				return false;
			}
			else
			{
				$gifts=array();
				foreach($tmp as $key=>$gift)
				{
					if( strpos( $gift['gift_type'], '1' )!== false ) 
					{
						$start_time=strtotime($gift['gift_begin_date']);
						$end_time=strtotime($gift['gift_end_date']);
						if($now_time<$start_time||$now_time>$end_time)
							continue;
					}
					if( strpos( $gift['gift_type'], '2' ) !== false ) 
					{
						if($gift['gift_total_num']<=0)
							continue;
					}
					$gifts[]=$gift;
				}
				$totalNum=count($gifts);
				$start=($cpage-1)*$perpage;
				if($totalNum===0||$start>=$totalNum)
					return false;
				else
				{
					$resultGifts=array_slice($gifts, $start, $perpage);
					$cacheManager->Set( "gift_totalnum", $totalNum, CNS_COUPON_GIFT );
					$cacheManager->Set( "gift_list_".$perpage."_".$cpage, $resultGifts, CNS_COUPON_GIFT );
					return $resultGifts;
				}
			}
		}
		
		public function GetHotGifts( $count=10 )
		{
			$cacheManager = GetCacheManager();
			$re = $cacheManager->Get( "HotGifts_".$count, CNS_COUPON_GIFT );
			
			if( $re !== false )
				return $re;
				
			$sql = "select g.gift_id, g.gift_name, g.gift_picture, g.gift_begin_date,
						 g.gift_end_date, g.gift_total_num, g.gift_type, g.gift_status,
						 (case WHEN gift_history_id IS NULL THEN 0 ELSE count(*) END ) as buy_num
				    from gift g
				   left join gift_history gh on g.gift_id = gh.gift_id
				   group by g.gift_id
				   having g.gift_status = 1
				   order by buy_num desc";

			$tmp = $this->db->GetPlan($sql);

			if( $tmp == false )
			{
				return false;
			}
			else
			{
				$gifts = array();
				$now = GetCurrentDate();
				$now_time = strtotime($now);
				
				foreach( $tmp as $key => $gift )
				{
					$types = explode( ",",$gift['gift_type'] );
					if( in_array("1", $types) )
					{
						$start_time = strtotime( $gift['gift_begin_date'] );
						$end_time = strtotime( $gift['gift_end_date'] );
						if( $now_time < $start_time || $now_time > $end_time )
							continue;
					}
					if(in_array("2", $types))
					{
						if( $gift['gift_total_num'] <= 0 )
							continue;
					}
					
					$gifts[] = $gift;
				}
				if( count($gifts) === 0 )
					return false;
				else
				{
					$hotGifts = array_slice($gifts, 0, $count);
					$cacheManager->Set( "HotGifts_".$count, $hotGifts, CNS_COUPON_GIFT );
					return $hotGifts;
				}
			}
		}
		
		public function GetGiftHistory( $count=12 )
		{
			$sql="select gh.user_id, ubi.nick, 
						 gh.gift_id, g.gift_name, g.gift_status, g.gift_win_rate, 
						 TIMESTAMPDIFF( MINUTE, gh.gift_exchange_date, NOW()) as timediff 
					from user_basic_info ubi, 
						 gift g, 
						 gift_history gh 
					where gh.gift_id = g.gift_id 
					  and gh.user_id = ubi.id 
					  and gh.note2<>'0' 
					order by gh.gift_exchange_date desc limit 0," . $count;
			
			$result=$this->db->GetPlan($sql);
			
			if(!$result)
				return false;

			$eventList=array();
			foreach($result as $key=>$value)
			{
				if($value['timediff']>=0&&$value['timediff']<60)
					$value['timediff']=$value['timediff'].'分钟前';
				else
				{
					if($value['timediff']>=60&&$value['timediff']<1440)
						$value['timediff']=floor($value['timediff']/60).'小时前';
					else
					{
						if($value['timediff']>=1440&&$value['timediff']<43200)
							$value['timediff']=floor($value['timediff']/1440).'天前';
						else
							$value['timediff']=floor($value['timediff']/43200).'月前';
					}
				}
				$eventList[]=$value;
			}
			return $eventList;
			//return $this->db->GetPlan($sql, true, CNS_COUPON_GIFT, 'RecentGiftHistory');
		}
		
		public function GetGiftByID( $giftId )
		{
			$sql=" select * from gift where gift_status=1 and gift_id= $giftId ";
			return $this->db->GetRow($sql);
		}
		
		public function GetHistoryByGiftId( $giftId, $count=20 )
		{
			$sql="	select ubi.nick, 
						   gh.*,
						   g.gift_name 
					  from (select * from gift_history where gift_id = $giftId order by note2 desc, gift_exchange_date desc
					   limit 0, $count ) gh
					  inner join user_basic_info ubi
					  inner join gift g
					 where ubi.id = gh.user_id
			 		   and g.gift_id = gh.gift_id";
			
			return $this->db->GetPlan( $sql );
		}
		
	/*
		 * 用户获取优惠券函数
		 * $coupon: 返回优惠券信息
		 * return 1， 获取成功
		 * return 2， 无效的礼品
		 * return 3， 用户兑换数目超过剩余上限
		 * return 4， 用户E币不够
		 * return 5, 内部错误
		 */
		public function ExchangeGift( $userId, $giftId, $giftNote, $quantity = 1 )
		{
			$now=GetCurrentDate();
			
			$this->db->BeginTransaction();
			try
			{
				// "for update" will prevent the dirty data
				$sql="select * from gift where gift_status=1 and gift_id = $giftId for update";
				
				$gift = $this->db->GetRow( $sql );
				if( $gift === false ) {
					$this->db->Commit();
					return 2;
				}
				
				$types = explode(",",$gift['gift_type']);
				if(	in_array("1", $types) )
				{
					$now_time = strtotime($now);
					$start_time = strtotime( $gift['gift_begin_date'] );
					$end_time = strtotime( $gift['gift_end_date'] );
					if( $now_time < $start_time || $now_time > $end_time ) {
						$this->db->Commit();
						return 2;
					}
				}
				if(in_array("2", $types))
				{
					if( $gift['gift_total_num'] <= 0 ) {
						$this->db->Commit();
						return 2;
					}
					if( $gift['gift_total_num'] < $quantity ) {
						$this->db->Commit();
						return 3;
					}
				}

				//Check enough coin
				if( $gift['gift_per_price']>0)
				{
					$cost = $gift['gift_per_price'] * $quantity;
					$userDAO=GetUserDAO();
					if( $userDAO->GetCoinByUid($userId) < $cost ){
						$this->db->Commit();
						return 4;
					}
				}


                                $giftNote2 = '';
                                $lottery = 0;
                                $process_status = 0;
                                if( floatval($gift['gift_win_rate']) < 1 )
                                {
                                    $range = intval( floatval($gift['gift_win_rate']) * 1000 );
                                    $seed = rand( 1, 1000 );
                                    if( $seed <= $range ){
                                        $giftNote2 = '1'; //bingo
                                        $lottery = 1;
                                    }
                                    else{
                                        $giftNote2 = '0';
                                        $lottery = 2;
                                        $process_status = 1;
                                    }
                                }


				//step 1, reduce the coin of user
				if( $gift['gift_per_price'] > 0 )
				{
					$cost = $gift['gift_per_price'] * $quantity;
					$sql = "update user_statistic set coins = coins - $cost where user_id = $userId ";
					$this->db->Update( $sql );
				}
				
				//step 2, reduce the gift total number if necessary
				if(in_array("2", $types))
				{
					$sql="update gift set gift_total_num = gift_total_num - $quantity where gift_id = $giftId ";
					$this->db->Update( $sql );
				}
				
								
				//step 3, log the history
				if( $gift['gift_per_price'] > 0 )
				{
					//if necessary, modify the value of $status into 0
					$sql = "insert into gift_history(user_id, gift_id, gift_exchange_quantity, gift_exchange_date, note1, note2, process_status) 
							values( $userId, $giftId, $quantity, '$now', '$giftNote', '$giftNote2', $process_status )";
					$this->db->Insert( $sql );
				}
				
				$this->db->Commit();

                                if( $lottery == 1 )
                                    return 6;
                                else if( $lottery == 2 )
                                    return 7;

                                return 1;
                               
			}
			catch( Exception $e )
			{
				$this->db->Rollback();
		    	return 5;
			}
		}
	}
?>